"""
Python是支持继承的面向对象语言，派生类的定于语法如下所示:
    class DerivedClassName(BaseClassName):
        <statement-1>
        .
        .
        .
        <statement-2>

父类BaseClassName必须作用与包含派生类定义的作用域中，当然，也允许用其他任意表达式代替基类位置
例如当来积累定义在另外一个模块的时候
    class DerivedClassName(modname.BaseClassName)

参考文档：https://docs.python.org/zh-cn/3/tutorial/classes.html#inheritance
"""

# 定义一个基类
from typing import SupportsAbs
from 类.实例对象.instance import testInstanceObject
from 类.类的对象.classObject import testClassObject


class Person:
    """
    基类包含简单的属性，但是属性不像C++那样可以声明为私有变量
    """
    def __init__(self, name, age):
        self.name, self.age = name, age
    
    def getName(self):
        return self.name
    
    def getAge(self):
        return self.age
    
# Person的派生类Stu
class Stu(Person):
    """
    Stu和Person的作用域是一样的

    派生类可能会重写基类的方法，因为方法在调用同一对象的其他方法时没有特殊权限
    也就是说，如果派生类和父类的方法一样，那么派生类的方法将会覆盖父类方法，就是调用的是派生类的方法

    对于C++程序员的提示：Python中所有的方法其实都是virtual方法

    在派生类的继承方法并非是为了简单地替换同名方法，一般而言是想要拓展其功能
    简单调用基类方法的方法如下：
        BaseClassName.methonName(self, arguments)
    但是仅当此基类可在全局作用域中以BaseClassName的名称被访问时可以使用这种方式
    """

    # 构造函数
    def __init__(self, name, age, id):
        # 调用父类构造函数的方法
        Person.__init__(name, age)
        # 也可以使用super方法来寻找构造函数
        # super.__init__(name, age)
        self.id = id

    def getMessage(self):
        return str(self.getName()) + " " + str(self.getAge()) + " " + str(self.id)

def testInheritance():
    """
    继承的实例
    """

    # 派生类和普通类其实没有声明区别，直接当作普通类使用就行了
    # 也需要创建实例对象，方法的使用也是如此，可以简单理解为深度搜索，先在派生类找，在去父类找

    # 创建一个对象
    person = Person("Bill", 23)
    stu = Stu("Alan", 23, 1001)

    print("person.getName() is {}".format(person.getName()))
    print("stu.getMessage() is {}".format(stu.getMessage()))

    # Python有两个内置的函数可以被用于继承机制:
    #
    # -使用isinstance()来检查一个实例的类型，例如isinstance(obj, int)仅会在 obj.__class__ 为int或某个派生自int的类时为True。
    #
    # -使用issubclass()来检查类的继承关系: 
    # issubclass(bool, int)为True因为bool是int的子类。
    # 但是，issubclass(float, int)为False，因为float不是int的子类。
    
    print("isinstance(stu, Stu) is {}".format(isinstance(stu, Stu)))
    print("not isinstance(person, Stu) is {}".format(not isinstance(person, Stu)))

    print("isinstance(person, Person) is {}".format(isinstance(person, Person)))
    print("isinstance(person, Stu) is {}".format(isinstance(person, Stu)))

    print("issubclass(person, Person) is {}".format(issubclass(person, Person)))
    print("issubclass(stu, Person) is {}".format(issubclass(stu, Person)))

testInheritance()
        